/**************************************************************************//**
 * @file     uart_buf.c
 * @brief    stm32f1xx uart BUF 管理
 * @version  V0.0.1
 * @date     2020-02-01
 ******************************************************************************/
/*
 * Copyright (c) 2020, 2020 by xiao xiang. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * is freely granted, provided that this notice is preserved.
 */
#include "common.h"
#include "stm32f1xx.h"
#include "hal_stm32f1xx_uart_api.h"

#include "uart_buf.h"

// UART BUF管理
char g_arUartTransmit[UART_TRANSMIT_BUF_MAX_LEN];
char g_arUartReceive[UART_RECEIVE_BUF_MAX_LEN];
ST_USART_BUF_CTRL g_stUartTransmit;
ST_USART_BUF_CTRL g_stUartReceive;

/**
 * @brief  USART BUF初始化配置函数
 * @note   无
 * @param  pstUsartInit 初始化结构体
 * @retval 无
 */
void UART_BufInit(void)
{
    // 初始化UART发送BUF
    g_stUartTransmit.head = 0;
    g_stUartTransmit.tail = 0;
    g_stUartTransmit.pBuf = g_arUartTransmit;
    g_stUartTransmit.bufLen = UART_TRANSMIT_BUF_MAX_LEN;

    // 初始化UART接收BUF
    g_stUartReceive.head = 0;
    g_stUartReceive.tail = 0;
    g_stUartReceive.pBuf = g_arUartReceive;
    g_stUartReceive.bufLen = UART_RECEIVE_BUF_MAX_LEN;
    
    return;
}

// 将要发送的数据保存到发送BUF里
void UartTransmitBufSave(char *pSaveBuf)
{
    char *c = pSaveBuf;

    __disable_irq();

    while (*c != '\0') {
        if (((g_stUartTransmit.tail + 1) % UART_TRANSMIT_BUF_MAX_LEN) == g_stUartTransmit.head) {
            // 如果尾指针加1等于头指针，说明BUF满了，直接丢弃返回
            return;
        }

        // tail永远指向的是一个空闲位，直接保存一个字符
        g_stUartTransmit.pBuf[g_stUartTransmit.tail] = *c;
        c++;
        g_stUartTransmit.tail = (g_stUartTransmit.tail + 1) % UART_TRANSMIT_BUF_MAX_LEN;
    }

    __enable_irq();

    return;
}

// 从要发送的BUF里读取一个字节
char UartTransmitBufLoad(void)
{
    char c;

    __disable_irq();

    if (g_stUartTransmit.head == g_stUartTransmit.tail) {
        // 首尾相等说明队列为空，直接返回0
        return 0;
    }

    // 如果不为空，直接返回HEAD指向的第一个字符，并且指针偏移一位
    c = g_stUartTransmit.pBuf[g_stUartTransmit.head];
    g_stUartTransmit.head = (g_stUartTransmit.head + 1) % UART_TRANSMIT_BUF_MAX_LEN;

    __enable_irq();

    return c;
}